<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script src="https://unpkg.com/socket.io-client@4.1.2/dist/socket.io.js"></script>
<script>
  const socket = io(
    "ws://localhost:3000",
    {
      reconnection: false,
      timeout: 2000, //默认值 20000
      autoConnect: false  //默认为true
      /*
        设置为false后, 就需要以下这样连接
        socket.connect();
        // or
        socket.io.open();
      */
    }
  );

  socket.connect();

  // 下面这俩个 实际用起来貌似是一样的 但官方说 socket.on("connect_error") ---> Fired when an namespace middleware error occurs.  ---> https://socket.io/docs/v4/client-api/#Event-%E2%80%98connect-error%E2%80%99
  //但实际上 不论是初次连接失败 还是重新连接失败 这俩都会触发
  //且 connect_error 先触发
  socket.io.on("error", (error) => {
    console.log('socket.io on error--- --- ---');

    //todo 注意 我们本地超时时间设置为2s, 服务器我们对一个连接做了16秒的占用, 也是说只有第一个能访问, 第二个访问肯定会超时,  也就会打印如下
    console.log(error);
    /*
      socket on  connect_error--- --- ---
      client2.html:38 Error: timeout
          at manager.js:147
    */
    // ...
  });
  socket.on("connect_error", (error) => {
    console.log('socket on  connect_error--- --- ---');
    console.log(error);
    /*
      socket.io on error--- --- ---
      client2.html:33 Error: timeout
          at manager.js:147
    */
    // ...
  });

  const tryReconnect = () => {
    console.log('5秒后重连');
    setTimeout(() => {
      //<del>socket.io.open 等价于 socket.connect();</del>
      console.log('--- --- --- 重连 --- --- ---');
      socket.io.open((err) => {
        if (err) {
          console.log('socket.io.open err --- --- ---');
          tryReconnect();
        }else {
          // socket.connect(); //重连的时候就不用再connect一次了, 否则会触发两次  socket.on("connect")
        }
      });
    }, 1000 * 5);
  }
  socket.on("disconnect", () => {
    console.log('disconnect--- --- ---');
    tryReconnect()
  });

  socket.on("connect", () => {
    console.log('--- --- ---socket.on connect--- --- ---');

    // either with send()
    // 使用send发送的消息 对端固定使用 on message 来接受
    // 发送的类型不止字符串 也可以是个对象(json) 或则 buffer
    socket.send("Hello!");

    // or with emit() and custom event names
    // 不像.send, .emit能够自定义 对端 需要监听的事件类型
    // socket.emit("salutations", "Hello!", { "mr": "john" }, Uint8Array.from([1, 2, 3, 4]));
  });

  // handle the event sent with socket.send()
  socket.on("message", data => {
    console.log('--- --- ---socket.on message--- --- ---');
    console.log(data);
  });

  // handle the event sent with socket.emit()
  /*socket.on("greetings", (elem1, elem2, elem3) => {
    console.log('--- --- ---socket.on greetings--- --- ---');
    console.log(elem1, elem2, elem3);
    console.log(typeof elem1, typeof elem2, typeof elem3);
    //string object object
    //说明如果发送的是对象(json) 或则 buffer,
    //在底层都会帮我们解析好 变成对应的类型 不用我们手动解析
  });*/
</script>
</body>
</html>
